///////////////////////////////////////////////////////////////////////////////
//
//  Copyright (C) 2007-2009 ILOG, S.A.
//  All Rights Reserved.
//  The following is ILOG Source Code.  No modifications may be made to the  
//  ILOG Source Code.  Any usage of the ILOG Source Code is subject to 
//  the terms and conditions of the ILOG End User License Agreement   
//  applicable to this ILOG software product.
//
///////////////////////////////////////////////////////////////////////////////

package ilog.gauges.gaugesClasses.rectangular
{
  /**
   * The <code>RectangularScaleRelatedRenderer</code> is the base class for visual 
   * rectangular elements that need a scale to position themselves, like tracks
   * or marker renderers. Optionally, a scale-related renderer can be considered
   * as the logical scale master, in which case it is in charge of configuring the 
   * logical scale for correct data transformations.
   *  
   * @mxml
   *  
   * <p>The <code>&lt;RectangularScaleRelatedRenderer&gt;</code> tag inherits all the 
   * properties of its parent classes and adds the following properties:</p>
   *  
   * <pre>
   * &lt;RectangularScaleRelatedRenderer
   *   <strong>Properties</strong>
   *   scale="<i>IScale, No Default</i>"
   *   master="false|true"
   *  /&gt;
   * </pre>
   * 
   * @see ilog.gauges.gaugesClasses.rectangular.IRectangularScale
   * @see #master
   */  
  public class RectangularScaleRelatedRenderer extends RectangularGaugeElement
  {
    private var _scale:IRectangularScale;
    private var _scaleSet:Boolean = false;
  
    /**
     * Constructor.
     */
    public function RectangularScaleRelatedRenderer()
    {      
    }
  
    [Inspectable(category="Gauge")]      
  
    /**
     * The scale that relates to this gauge element. If the <code>scale</code>
     * property is not explicitely set, the first scale of the holding
     * gauge will be used.
     *
     * @default null
     * 
     * @see ilog.gaugesClasses.GaugeBase#scales
     */  
    public function get scale():IRectangularScale 
    {
      // auto discovery, do we have an explicit scale? If not do we have
      // scales[0] as a scale? If not let's use it.
      if (!_scaleSet && gauge.scales.length > 0 && _scale != gauge.scales[0]) {
        // set it explicitely to register the element.
        setScale(gauge.scales[0]);
      }
      return _scale;
    }
    
    /**
     * @private
     */
    public function set scale(value:IRectangularScale):void
    {
      if (value != _scale) {
        setScale(value);  
      }
      _scaleSet = (value != null);
    }
    
    private function setScale(value:IRectangularScale):void 
    {
      if (_scale != null)
        _scale.unregisterElement(this);
      _scale = value;
      if (_scale != null) 
        _scale.registerElement(this);      
    }
    
    private var _master:Boolean = false;
    
    [Inspectable(category="Gauge")]
            
    /**
     * Specifies whether this element is the scale master or not. The scale master is the
     * element in charge of setting the <code>length</code> and <code>offset</code>
     * properties of the scale. All other elements related to this scale will then
     * share the same transformation space to transform values to pixels and 
     * conversely. 
     * <p>
     * A scale can only have one scale master, thus only one element 
     * should have this property set to <code>true</code>. 
     * </p>
     * <p>
     * The default value is <code>false</code>, except for 
     * <code>RectangularScaleRenderer</code> for which it is <code>true</code>.
     * </p>
     * @default false
     * @see ilog.gauges.rectangular.renderer.RectangularScaleRenderer
     */
    public function get master():Boolean
    {
      return _master;
    }
    
    public function set master(value:Boolean):void 
    {
      _master = value;
    }
    
    /**
     * The offset that is set on the scale if this element is the scale master.
     * 
     * @default 0
     * @see #master
     */
    protected function get displayOffset():Number
    {
      return 0; 
    }

    /**
     * The length that is set on the scale if this element is the scale master.
     * The default value is the width of the element if the gauge is horizontal,
     * and the height of the element if the gauge is vertical.
     * 
     * @see #master
     * @see ilog.gauges.rectangular.RectangularGauge#direction
     */    
    protected function get displayLength():Number
    {
      return (gauge.direction == "horizontal" ? unscaledWidth : unscaledHeight);    
    }
    
    /**
     * This method clears the graphics and sets the <code>offset</code> and 
     * <code>length</code> properties on the scale, if the element is the scale
     * master. You should not forget to call this method in your own subclass
     * to make sure this work is automatically done for you.
     * 
     * @param unscaledWidth Specifies the width, in pixels, of the component
     * in the component's coordinates, regardless of the value of the
     * <code>scaleX</code> property of the component.
     *
     * @param unscaledHeight Specifies the height, in pixels, of the component
     * in the component's coordinates, regardless of the value of the
     * <code>scaleY</code> property of the component. 
     * 
     * @see #master
     */ 
    protected override function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void
    {
      graphics.clear();
      if (_master) {
        scale.offset = displayOffset;
        scale.length = displayLength;
      }
    }
  }
}
